﻿#include "FITKAcousticsVTKGraphObjectFESubSystems.h"
#include "FITKAcousticsVTKSharedDataManager.h"
#include "FITKAcousticsVTKGraphActor.h"

#include "FITK_Kernel/FITKCore/FITKAbstractGraphObject.h"
#include "FITK_Kernel/FITKCore/FITKCoreMacros.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsFEModel.h"
#include "FITK_Interface/FITKVTKAlgorithm/FITKGraphActor.h"

#include <vtkMapper.h>
#include <vtkLookupTable.h>
#include <vtkProperty.h>
#include <vtkCompositeDataGeometryFilter.h>
#include <vtkCellData.h>
#include <vtkMultiBlockDataSet.h>
#include <vtkExtractBlock.h>

namespace Exchange
{
    FITKAcousticsVTKGraphObjectFESubSystems::FITKAcousticsVTKGraphObjectFESubSystems(Acoustics::FITKAcousticsFEModel * model) :
        FITKAcousticsVTKGraphObjectMergedData(model)
    {
        if (model) {
            m_feSubManager = model->getFESubSysManager();
        }
    }

    FITKAcousticsVTKGraphObjectFESubSystems::~FITKAcousticsVTKGraphObjectFESubSystems()
    {

    }

    void FITKAcousticsVTKGraphObjectFESubSystems::updateById(int dataId, bool forceUpdate)
    {
        //判断当前数据是否存在
        int dataIndex = -1;
        vtkDataSet* dataSet = FITKAcousticsVTKSharedDataManager::GetInstance()->getFESubSystemDataSet(dataId, dataIndex);
        Q_UNUSED(dataIndex);

        //如果数据不存在或需要强制刷新
        if (dataSet == nullptr || forceUpdate == true) {
            //更新数据
            FITKAcousticsVTKSharedDataManager::GetInstance()->updateFESubSystemDataSet(dataId);
        }
        else {
            //更新颜色
            FITKAcousticsVTKSharedDataManager::GetInstance()->updateFESubSystemDataSetColor(dataId);
        }
    }

    void FITKAcousticsVTKGraphObjectFESubSystems::updateVisibility()
    {
        // Update the blocks' visibility.
        int index = 0;
        if (m_feSubManager && m_extractBlock && m_multiBlockDataSet )
        {
            m_multiBlockDataSet->ReleaseData();
            m_extractBlock->RemoveAllIndices();

            for (Acoustics::FITKAbstractFESubSys* subSys : m_feSubManager->getSubSysByType(m_FESubSysTypeEnum)) {
                if (!subSys) {
                    continue;
                }

                //判断数据是否可见
                if (!subSys->isEnable()) {
                    continue;
                }

                int dataIndex = -1;
                vtkDataSet* ds = FITKAcousticsVTKSharedDataManager::GetInstance()->getFESubSystemDataSet(subSys->getDataObjectID(), dataIndex);

                if (dataIndex < 0) {
                    continue;
                }

                // Update the color.
                updateById(subSys->getDataObjectID(), false);

                m_multiBlockDataSet->SetBlock(index, ds);
                m_extractBlock->AddIndex(index);
                index++;
            }
        }

        this->Superclass::updateVisibility();
    }

    void FITKAcousticsVTKGraphObjectFESubSystems::updateByDataColor()
    {
        if (!m_fActor) {
            return;
        }

        vtkLookupTable* lookupTable = getActorLut(m_fActor);
        if (lookupTable == nullptr)return;

        // Enable the cell data color array.
        m_fActor->setScalarVisibility(true);
        m_fActor->setScalarModeToUseCellFieldData();
        m_fActor->selectScalarArray(DATA_COLOR_ARRAY_NAME);

        // Update the look up table.
        lookupTable->SetVectorModeToRGBColors();
        lookupTable->Build();

        // Reset the transparent.
        m_fActor->GetProperty()->SetOpacity(1.);

        // Update the pipeline.
        if (m_comp2Poly) {
            m_comp2Poly->Modified();
        }
    }

    int FITKAcousticsVTKGraphObjectFESubSystems::getShapeIdByVTKCellId(int vtkId, FITKAcousticsVTKCommons::ShapeMeshAbsEnum topAbsShapeType)
    {
        if (!m_fActor) {
            return -1;
        }

        // Get the input dataset.
        vtkMapper* mapper = m_fActor->GetMapper();
        if (!mapper) {
            return -1;
        }

        vtkDataSet* dataSet = mapper->GetInputAsDataSet();
        if (!dataSet) {
            return -1;
        }

        vtkCellData* cellData = dataSet->GetCellData();
        if (!cellData) {
            return -1;
        }

        switch (topAbsShapeType)
        {
        case Exchange::FITKAcousticsVTKCommons::STA_FACE:
        {
            // Get the id array.
            vtkIntArray* idArray = vtkIntArray::SafeDownCast(cellData->GetArray(DATA_SUB_ID_ARRAY_NAME));
            if (!idArray) {
                return -1;
            }

            int nVal = idArray->GetNumberOfValues();
            if (vtkId >= nVal) {
                return -1;
            }

            int dataId = idArray->GetValue(vtkId);
            return dataId;
        }
        case Exchange::FITKAcousticsVTKCommons::MT_Element:
        {
            // Get the id array.
            vtkIntArray* idArray = vtkIntArray::SafeDownCast(cellData->GetArray(DATA_ELEM_ID_ARRAY_NAME));
            if (!idArray) {
                return -1;
            }

            int nVal = idArray->GetNumberOfValues();
            if (vtkId >= nVal) {
                return -1;
            }

            int dataId = idArray->GetValue(vtkId);
            return dataId;
        }
        default:
            // Return data id.
            return this->Superclass::getShapeIdByVTKCellId(vtkId, topAbsShapeType);
        }

        return -1;
    }

    void FITKAcousticsVTKGraphObjectFESubSystems::init()
    {
        this->Superclass::init();
    }
}